package org.xiaojl.xcloud.tools.gateway;

import java.io.Serializable;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Enumeration;

import com.fasterxml.jackson.annotation.JsonFormat;

/**
 * <p> Title: RpcResult </p>
 *
 * <p>
 * Description: 内部服务之间的RPC调用统一结果类<br>
 * 
 * <pre class="code">
 *	{
 *	    "status": 响应状态：：true-成功，false-失败,
 *	    "msg": "{响应信息}",
 *	    "devMsg": "{详细开发信息}",
 *	    "requestId": "01234567-89ab-cdef-0123-456789abcdef",
 *	    "hostId": "{server identity}",
 *	    "serverTime": "2014-01-01 12:00:00",
 *		"returnData":返回数据对象
 *	}
 * </pre>
 * </p>
 *
 * @author jilong.xiao
 * @date 2018年4月25日
 */
public class RpcResult implements Serializable {
	/** serialVersionUID */
	private static final long serialVersionUID = 1L;
	/**
	 * 响应状态：true-成功，false-失败
	 */
	private boolean status;
	/**
	 * 响应信息
	 */
	private String msg;
	/**
	 * 详细开发信息，给开发人员查看的信息
	 */
	private String devMsg;
	/**
	 * 请求ID
	 */
	private String requestId;
	/**
	 * 机器ID
	 */
	private String hostId;
	/**
	 * 服务响应时间
	 */
	@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
	private Date serverTime;
	/**
	 * 返回数据对象
	 */
	private Object returnData;
	
	public static RpcResult fail(String msg,Object retData){
		String hId = RpcResultKit.getLocalIp();
		Date stime = new Date();
		String rId = "";
		return new RpcResult(false, msg, "异常信息请查看returnData的值", rId,hId,stime,retData);
	}
	
	public static RpcResult fail(String msg,String devMsg,Object retData){
		String hId = RpcResultKit.getLocalIp();
		Date stime = new Date();
		String rId = "";
		return new RpcResult(false, msg, devMsg, rId,hId,stime,retData);
	}
	
	public static RpcResult success(Object retData){
		String hId = RpcResultKit.getLocalIp();
		Date stime = new Date();
		String rId = "";
		return new RpcResult(true, "调用成功", "", rId,hId,stime,retData);
	}
	
	/**
	 * <p>Title: newInstance</p>  
	 *
	 * <p>Description: </p>  
	 *
	 * @param status 响应状态：true-成功，false-失败
	 * @param msg 响应信息
	 * @param devMsg 详细开发信息，给开发人员查看的信息
	 * @param requestId 请求ID
	 * @param retData 返回数据对象
	 * @return
	 */
	public static RpcResult newInstance(boolean status,String msg,String devMsg, String requestId,Object retData){
		String hId = RpcResultKit.getLocalIp();
		Date stime = new Date();
		return new RpcResult(status,msg,devMsg,requestId,hId,stime,retData);
	}
	public RpcResult(){}
	public RpcResult(boolean status, String msg, String devMsg, String requestId, String hostId, Date serverTime,
			Object returnData) {
		super();
		this.status = status;
		this.msg = msg;
		this.devMsg = devMsg;
		this.requestId = requestId;
		this.hostId = hostId;
		this.serverTime = serverTime;
		this.returnData = returnData;
	}
	public boolean isStatus() {
		return status;
	}
	public void setStatus(boolean status) {
		this.status = status;
	}
	public String getMsg() {
		return msg;
	}
	public void setMsg(String msg) {
		this.msg = msg;
	}
	public String getDevMsg() {
		return devMsg;
	}
	public void setDevMsg(String devMsg) {
		this.devMsg = devMsg;
	}
	public String getRequestId() {
		return requestId;
	}
	public void setRequestId(String requestId) {
		this.requestId = requestId;
	}
	public String getHostId() {
		return hostId;
	}
	public void setHostId(String hostId) {
		this.hostId = hostId;
	}
	public Date getServerTime() {
		return serverTime;
	}
	public void setServerTime(Date serverTime) {
		this.serverTime = serverTime;
	}
	public Object getReturnData() {
		return returnData;
	}
	public void setReturnData(Object returnData) {
		this.returnData = returnData;
	}
	@Override
	public String toString() {
		return "RpcResult [status=" + status + ", msg=" + msg + ", devMsg=" + devMsg + ", requestId=" + requestId
				+ ", hostId=" + hostId + ", serverTime=" + serverTime + ", returnData=" + returnData + "]";
	}
	
	static class RpcResultKit{
		/**
		 * 获取本地IP地址
		 */
		public static String getLocalIp() {
			if (isWindowsOS()) {
				return getLocalHostAddress();
			} else {
				return getLinuxLocalIp();
			}
		}

		/**
		 * 判断操作系统是否是Windows
		 * @return
		 */
		public static boolean isWindowsOS() {
			boolean isWindowsOS = false;
			String osName = System.getProperty("os.name");
			if (osName.toLowerCase().indexOf("windows") > -1) {
				isWindowsOS = true;
			}
			return isWindowsOS;
		}
		
		/**
		 * 获取本地Host地址
		 */
		public static String getLocalHostAddress(){
			try {
				return InetAddress.getLocalHost().getHostAddress();
			} catch (UnknownHostException e) {
				System.err.println("获取ip地址异常:"+e.getMessage());
			}
			return "127.0.0.1";
		}

		/**
		 * 获取Linux下的IP地址
		 *
		 * @return IP地址
		 * @throws SocketException
		 */
		private static String getLinuxLocalIp(){
			String ip = "";
			try {
				for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
					NetworkInterface intf = en.nextElement();
					String name = intf.getName();
					if (!name.contains("docker") && !name.contains("lo")) {
						for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
							InetAddress inetAddress = enumIpAddr.nextElement();
							if (!inetAddress.isLoopbackAddress()) {
								String ipaddress = inetAddress.getHostAddress().toString();
								if (!ipaddress.contains("::") && !ipaddress.contains("0:0:")
										&& !ipaddress.contains("fe80")) {
									ip = ipaddress;
								}
							}
						}
					}
				}
			} catch (SocketException ex) {
				System.err.println("获取ip地址异常:"+ex.getMessage());
				ip = "127.0.0.1";
			}
			return ip;
		}
	}
}
